/*
 * Copyright (c) 2001, Jan Nieuwenhuizen.
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by DJ Delorie <dj@cygnus.com>
 *            Jan Nieuwenhuizen <janneke@gnu.org>
 * 
 * Modified by yospaly, 2009-1-20
 *
 */

/* The purpose of this file is to provide functions for the invocation
 of install scripts. */

#include <wx/wx.h>
#include <wx/file.h>
#include <wx/filename.h>

#include "mounttable.h"
#include "scriptrunner.h"

void ScriptRunner::init_run_script() {
	MountTable& mt = MountTable::get();
	
	for (int i = 0; i<_shells.GetCount(); i++) {
		_sh = mt.cygpath(_shells[i]);
		_sh.Replace(_T("/"), _T("\\"));
		
		if ( wxFile::Exists(_sh) ) {
			break;
		}
	}
	
	wxString bin_path = wxFileName(mt.cygpath(_T("/bin")), _T("")).GetFullPath();
	wxString usr_bin_path = wxFileName(mt.cygpath(_T("/usr/bin")), _T("")).GetFullPath();

	bin_path.Replace(_T("/"), _T("\\"));
	usr_bin_path.Replace(_T("/"), _T("\\"));
	
	const wxString& new_path = wxString::Format(_T("%s;%s;%s"), 
			bin_path.c_str(), usr_bin_path.c_str(), _old_path.c_str() );
	
	::wxSetEnv(_T("PATH"), new_path);
	
	::wxSetEnv(_T("CYGWINROOT"), mt.get_root_dir());
	
	_cmd = _T("cmd.exe"); // we only support windows 2000 and higher
}

static long run(const wxString& sh, const wxString& args, const wxString& file,
		wxArrayString& output, wxArrayString& errors)
{
	wxString cmdline = wxString::Format(_T("%s %s %s"), 
			sh.c_str(), args.c_str(), file.c_str() );
	
	return ::wxExecute(cmdline, output, errors, wxEXEC_SYNC | wxEXEC_NOHIDE);
}

long ScriptRunner::_run_script(const wxString& dir, const wxString& pkg,
		const wxString& ext, wxArrayString& output, wxArrayString& errors) const
{
	MountTable& mt = MountTable::get();
	const wxString& posix_path = wxFileName(dir, pkg, ext).GetFullPath(wxPATH_UNIX);
	wxString native_path = wxFileName(mt.cygpath(posix_path)).GetFullPath();
	native_path.Replace(_T("/"), _T("\\"));
	
	if ( !wxFile::Exists(native_path) ) {
		return SCRIPT_NOT_FOUND;
	}

	/* Bail here if the script file does not exist.  This can happen for
	 example in the case of tetex-* where two or more packages contain a
	 postinstall script by the same name.  When we are called the second
	 time the file has already been renamed to .done, and if we don't
	 return here we end up erroniously deleting this .done file.  */
	long retval = 0L;
	
	if ( ext==CYGWIN_BASH_EXT ) {
		retval = ::run(_sh, _T("-c"), posix_path, output, errors);
	} else if ( ext==CYGWIN_CMD_EXT ) {
		retval = ::run(_cmd, _T("/c"), native_path, output, errors);
	} else
		return INCORRECT_FILE_EXT;

	/* if file exists then delete it otherwise just ignore no file error */
	::wxRenameFile(native_path, native_path+_T(".done"), true);

	return retval;
}

ScriptRunner::ScriptRunner() {
	::wxGetEnv(_T("PATH"), &_old_path);
    
    // Bash is guaranteed to exist, /bin/sh is not. Besides,
    // upgrading /bin/sh requires that /bin/sh not be used.
    _shells.Add(_T("/bin/bash.exe"));
    _shells.Add(_T("/usr/bin/bash.exe"));
}

ScriptRunner ScriptRunner::self;
